import Router from '@koa/router';
import logger from '../logger.js';
import response from '../response.js';
import db from '../mysqlHelper.js';
import moment from 'moment';
import redis from '../redisHelper.js';
import minuteRules from '../parkRules/minuteRules.js';
import publicMethod from '../publicMethod.js';


const router = new Router();
router.prefix('/api');

//车牌识别入场补充证据
// router.post(`/park/camera/carIn`, async (ctx) => {


function  YH_createPackage(cmd,addr){
    let buf=Buffer.alloc(5);
    buf.writeUInt8(0x02,0);
    buf.writeUInt8(cmd,1);
    buf.writeUInt8(addr,2);
    buf.writeUInt8(cmd^addr,3);
    buf.writeUInt8(0x03,4);
    return buf;
};
function YH_parsePackage(buf){
    if(buf.length<5){
        return null;
    }
    if(buf[0]!=0x02 || buf[buf.length-1]!=0x03){
        console.log('元鸿协议包头或包尾错误');
        return null;
    }
    let cmd=buf[1];
    let value=buf[2];
    let check=buf[3];
    if((cmd^value)!=check){
        console.log('元鸿协议包校验错误');
        return null;
    }
    return {cmd,value};
}

function getOpenGateCmd(gate_model, gate_sn,gate_ch) {
    if(gate_model == 'YH-01') {
        //元鸿道闸
        return YH_createPackage(0x81, gate_ch).toString('base64');
    }
    else if (gate_model == 'AK-01') {
        //安快道闸
       // return YH_createPackage(0x81, gate_ch);
    }
}

async function openGate(gate_model,camera_sn='', gate_sn='',gate_ch) {
    if (camera_sn != '')//如果有摄像头 摄像头透传控制开闸
    {
        //拼接透传参数
        let ip = await redis.getLotCameraInfo(camera_sn);
        if (ip == null) {
            ctx.body = response.fail('车位相机不在线');
            return;
        }
        let request_data = {
            sn: camera_sn,
            data:getOpenGateCmd(gate_model, gate_sn, gate_ch)
        }
        let url = `http://${ip}:82/api/camera/sendSerialData`;
        let res = await request_device_server(url, request_data, '车位相机透传开闸');
        if (res instanceof Error) {
            ctx.body = response.fail(`请求透传开闸失败 ${res.message}`);
            return;
        }
        if (res.code != 0) {
            ctx.body = response.fail(`请求透传开闸失败 ${res.msg}`);
            return;
        }
    } else if (gate_sn != '') {
        let ip = await redis.getLotGateInfo(gate_sn);
        if (ip == null) {
            ctx.body = response.fail('车位道闸不在线');
            return;
        }

        let url = `http://${ip}:82/api/gate/open`;
        let res = await request_device_server(url, request_data, '车位道闸开闸');
        if (res instanceof Error) {
            ctx.body = response.fail(`请求道闸开闸失败 ${res.message}`);
            return;
        }
        if (res.code != 0) {
            ctx.body = response.fail(`请求道闸开闸失败 ${res.msg}`);
            return;
        }
    }

}

//车辆入场
async function carIn(lot_id, plate, in_status, phone, openid) {
    //获到车位对应的信息
    const lotInfo = await db.query(`SELECT * FROM lot WHERE id = ?`, [lot_id]);
    if (lotInfo.length === 0) {
        return response.error('车位不存在');
    }
    if (lotInfo[0].enable !== 1) {
        return response.error('车位已被禁用');
    }

    let onpark = {
        project_id: lotInfo[0].project_id,
        lot_id: lotInfo[0].id,
        plate: plate,
        type: 3,
        billing_rules_id: lotInfo[0].billing_rules_id,
        in_time: moment().format('YYYY-MM-DD HH:mm:ss'),
        status: in_status,
        discount_time: 0,
        cam_channel: lotInfo[0].gate_ch,
        phone: phone,
        openid: openid

    }
    let res = await db.query(`INSERT INTO onpark SET ?`, [onpark]);
    if (res.affectedRows === 0) {
        return response.error('车辆入场失败');
    }
    openGate(lotInfo[0]);
    return response.success('车辆入场成功');
}


//车辆出场
async function carOut(lot_id) {
    //获到车位对应的信息
    const lotInfo = await db.query(`SELECT * FROM lot WHERE id = ?`, [lot_id]);
    if (lotInfo.length === 0) {
        return response.error('车位不存在');
    }
    if (lotInfo[0].enable !== 1) {
        return response.error('车位已被禁用');
    }
    //获取所属项目信息
    const projectInfo = await db.query(`SELECT project.name,project.path,isp.name as isp_name,project.isp_id FROM project left join isp on project.isp_id = isp.id WHERE project.id = ?`, [lotInfo[0].project_id]);
    if (projectInfo.length === 0) {
        return response.error('项目不存在');
    }

    let start_time = lotInfo[0].in_time;
    //计算费用
    if (discount_time > 0) {
        start_time = moment(start_time).add(discount_time, 'minutes')
    }
    let end_time = moment().format('YYYY-MM-DD HH:mm:ss');
    let fee = await minuteRules.calculate(start_time, end_time, lotInfo[0].billing_rules_id);
    if (fee == null) {
        return response.error('计算费用失败');
    }

    //生成占位订单
    let no_charge_park_record = {
        lot_name: lotInfo[0].lot_name,
        path: projectInfo[0].path,
        isp_name: projectInfo[0].isp_name,
        project_name: projectInfo[0].name,
        project_id: lotInfo[0].project_id,
        isp_id: projectInfo[0].isp_id,
        create_time: moment().format('YYYY-MM-DD HH:mm:ss'),
        amount: fee,
        pay_amt: fee,
        phone: lotInfo[0].phone,
        openid: lotInfo[0].openid,
        plate: lotInfo[0].plate,
        start_time: start_time,
        end_time: end_time.format('YYYY-MM-DD HH:mm:ss'),
        end_time: moment().format('YYYY-MM-DD HH:mm:ss'),
        use_time: moment(end_time).diff(moment(lotInfo[0].in_time), 'minutes'),
        jf_time: moment(end_time).diff(moment(start_time), 'minutes'),
        in_image: lotInfo[0].in_image
    }
    let sqls = [];
    sqls.push(`INSERT INTO no_charge_park SET ?`, [no_charge_park_record]);
    //删除在场记录
    sqls.push(`DELETE FROM onpark WHERE id = ?`, [lotInfo[0].id]);

    let res = await db.transaction(sqls);
    if (res.affectedRows === 0) {
        return response.error('车辆出场失败');
    }
    res = await publicMethod.autoRefundAndShare(lotInfo[0].phone, fee);
    if (res.code === 0) {
        return response.error(res.msg);
    }
    if (res.code === 1) {
        return response.success('车辆出场成功,退款成功');
    }
}



//车位相机识别到稳定入场后更新车位的待入场信息
router.post('/camera/carIn', async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if(body.camera_ch==null){
        ctx.body = response.fail('缺少必填字段 camera_ch');
        return;
    }
    if(body.camera_sn==null){
        ctx.body = response.fail('缺少必填字段 camera_sn');
        return;
    }
    if(body.plate==null){
        ctx.body = response.fail('缺少必填字段 plate');
        return;
    }
    if(body.pic==null){
        ctx.body = response.fail('缺少必填字段 pic');
        return;
    }
    let sql =` update lot set in_image='${body.pic}',in_plate='${body.plate}' where camera_ch='${body.camera_ch}' and camera_sn='${body.camera_sn}'`;
    let res = await db.query(sql);
    if(res.affectedRows==0){
        ctx.body = response.fail('车位不存在');
        return;
    }
    ctx.body = response.success('车牌识别入场成功');
    return;
});

//前端调用真实的车辆入场接口
router.post('/lot/carIn', async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }

    if(body.lot_id==null){
        ctx.body = response.fail('缺少必填字段 lot_id');
        return;
    }
    if(body.plate==null){
        ctx.body = response.fail('缺少必填字段 plate');
        return;
    }
    if(body.phone==null){
            ctx.body = response.fail('缺少必填字段 phone');
            return;
    }

    //联合查询获取收费规则
    let sql=`select billing_rules.id as billing_rule_id,billing_rules.name,lot.* from lot join billing_rules on lot.project_id=billing_rules.id where lot.id=${body.lot_id} and  billing_rules.type=1`;
    let lotInfo = await db.query(sql);
    if (lotInfo.length === 0) {
        console.log('车辆入场未查询到对应的收费规则',body.lot_id);
        ctx.body = response.fail('未找到收费规则');
        return;
    }
    let vehicle_type=3;
    let vehicle= await db.findOne('vehicle',{plate:body.plate,project_id:lotInfo[0].project_id});
    if(vehicle){
        vehicle_type=vehicle.type;
    }

    let onpark_vehicle={
        project_id:lotInfo[0].project_id,
        lot_id:lotInfo[0].id,
        plate:body.plate,
        type:vehicle_type,
        billing_rules_id:lotInfo[0].billing_rule_id,
        billing_rules_name:lotInfo[0].name,
        in_time:moment().format('YYYY-MM-DD HH:mm:ss'),
        in_image:body.lotInfo[0].in_image,
        status:1,
        discount_time:0,
        cam_ch:lotInfo[0].camera_ch,
        phone:body.phone,
    }
    if(body.openid!=null){
        onpark_vehicle.openid=body.openid;
    }
    let is_exist= await db.checkExist('onpark_vehicle',{lot_id:body.lot_id});
    let res =null;
    if(is_exist){
        res=await db.update('onpark_vehicle',onpark_vehicle,{lot_id:body.lot_id});
    }else{
        res=await db.create('onpark_vehicle',onpark_vehicle);
    }
    if(res instanceof Error){
        console.warn(`车辆${body.plate}入场失败 ${res.message}`)
        ctx.body = response.fail(`车辆${body.plate}入场失败 ${res.message}`);
        return;
    }
    await openGate(lotInfo[0].gate_model,lotInfo[0].camera_sn,lotInfo[0].gate_sn,lotInfo[0].gate_ch);
    ctx.body = response.success('车辆入场成功');
});

//按收费规则计算停车费用
async function calculateFee(start_time, end_time, billing_rules_id) {
    let fee = await minuteRules.calculate(start_time, end_time,billing_rules_id);
    if (fee == null) {
        console.warn('未查询到对应的收费规则', billing_rules_id);
        return 0;
    }
    return fee;
}

router.post('/camera/carOut',async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if(body.camera_ch==null){
        ctx.body = response.fail('缺少必填字段 camera_ch');
        return;
    }
    if(body.camera_sn==null){
        ctx.body = response.fail('缺少必填字段 camera_sn');
        return;
    }
    if(body.plate==null){
        ctx.body = response.fail('缺少必填字段 plate');
        return;
    }
    if(body.pic==null){
        ctx.body = response.fail('缺少必填字段 pic');
        return;
    }
    let onpark_vehicle=await db.findOne('onpark_vehicle',{plate:body.plate,lot_id:body.lot_id});
    if(onpark_vehicle==null){
        ctx.body = response.fail('车辆不在场');
        return;
    }
    if(onpark_vehicle.status!=1){
        ctx.body = response.fail('车辆已出场');
        return;
    }
    let  start_time=onpark_vehicle.in_time;
    //计算停车时间
    if(onpark_vehicle.discount_time>0){
        onpark_vehicle.in_time=moment(onpark_vehicle.in_time).add(onpark_vehicle.discount_time,'minutes');
    }else{
         onpark_vehicle.in_time=moment(onpark_vehicle.in_time);
    }
    let fee =await calculateFee(onpark_vehicle.in_time,moment(),onpark_vehicle.billing_rules_id);
    if( fee == null){
        console.warn('计算停车费用失败',onpark_vehicle.plate);
        ctx.body = response.fail('计算停车费用失败');
        return;
    }
    fee=fee*100;//转换为分
    let res =await publicMethod.autoRefundAndShare(onpark_vehicle.phone,fee,fee-(fee*0.006),0,0,onpark_vehicle.id,10);
    if(res.code==0){
        ctx.body = response.fail('自动退款和分账失败');
        return;
    }
    //车位表和项目信息表联表查询
    let sql =`select lot.*,project.path, project.name as project_name, isp.name as isp_name from lot join project on lot.project_id=project.id join isp on lot.isp_id=isp.id where lot.id=${onpark_vehicle.lot_id}`;
    let lotInfo = await db.query(sql);
    if (lotInfo.length === 0) {
        console.warn('车位不存在', onpark_vehicle.lot_id);
        ctx.body = response.fail('车位不存在');
        return;
    }
    let no_charge_park={
        lot_name:lotInfo[0].lot_name,
        path:lotInfo[0].path,
        isp_name:isp_name,
        project_name:lotInfo[0].project_name,
        create_time:moment().format('YYYY-MM-DD HH:mm:ss'),
        amount:fee,
        pay_amt:fee,
        phone:onpark_vehicle.phone,
        openid:onpark_vehicle.openid,
        plate:onpark_vehicle.plate,
        start_time:start_time,
        end_time:moment().format('YYYY-MM-DD HH:mm:ss'),
        use_time:onpark_vehicle.discount_time,
        jf_time:moment().diff(onpark_vehicle.in_time,'minutes'),
        in_image:onpark_vehicle.in_image,
        out_image:body.pic,
        isp_id:lotInfo[0].isp_id,
        project_id:lotInfo[0].project_id
    };
    let sqls=[];
    sqls.push(`INSERT INTO no_charge_park SET ?`,[no_charge_park]);
    //更新在场车辆状态
    sqls.push(`UPDATE onpark_vehicle SET status=0 WHERE id=?`,[onpark_vehicle.id]);
    res =await db.transaction(sqls);
    if(res instanceof Error){
        console.warn('车辆出场失败',res.message);
        ctx.body = response.fail('车辆出场失败');
        return;
    }

    ctx.body = response.success('车辆出场成功');
});




export { router };
